<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
use Symfony\Component\HttpFoundation\Response;

class RateLimitApi
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @param  string  $key 限流键名
     * @param  string|int  $maxAttempts 最大尝试次数
     * @param  string|int  $decayMinutes 衰减时间（分钟）
     * @return \Symfony\Component\HttpFoundation\Response
     */
    public function handle(Request $request, Closure $next, string $key = 'api', $maxAttempts = 60, $decayMinutes = 1): Response
    {
        try {
            // 转换参数类型（Laravel中间件参数都是字符串）
            $maxAttempts = (int) ($maxAttempts ?: 60);
            $decayMinutes = (int) ($decayMinutes ?: 1);
            
            $identifier = $this->resolveRequestSignature($request, $key);

            // 如果限流服务不可用，跳过限流检查
            try {
                if (RateLimiter::tooManyAttempts($identifier, $maxAttempts)) {
                    $seconds = RateLimiter::availableIn($identifier);
                    
                    return response()->json([
                        'code' => 429,
                        'message' => "请求过于频繁，请 {$seconds} 秒后再试",
                    ], 429)->withHeaders([
                        'Retry-After' => $seconds,
                        'X-RateLimit-Limit' => $maxAttempts,
                        'X-RateLimit-Remaining' => 0,
                    ]);
                }

                RateLimiter::hit($identifier, $decayMinutes * 60);
            } catch (\Exception $e) {
                // 如果限流服务失败，记录日志但继续处理请求
                \Log::warning('限流服务异常: ' . $e->getMessage());
            }

            $response = $next($request);

            // 尝试设置限流响应头
            try {
                $response->headers->set('X-RateLimit-Limit', $maxAttempts);
                $response->headers->set('X-RateLimit-Remaining', RateLimiter::remaining($identifier, $maxAttempts));
            } catch (\Exception $e) {
                // 忽略设置响应头的错误
            }

            return $response;
        } catch (\Exception $e) {
            \Log::error('RateLimitApi中间件异常: ' . $e->getMessage(), [
                'trace' => $e->getTraceAsString()
            ]);
            // 如果中间件失败，继续处理请求（不阻塞）
            return $next($request);
        }
    }

    /**
     * 解析请求签名
     *
     * @param Request $request
     * @param string $key
     * @return string
     */
    protected function resolveRequestSignature(Request $request, string $key): string
    {
        // 如果用户已登录，使用用户ID
        if ($user = $request->user()) {
            return $key . ':' . $user->id . ':' . $request->ip();
        }

        // 否则使用IP地址
        return $key . ':' . $request->ip();
    }
}

